﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#ifndef __BALANCE_SERVER_IMP_H__
#define __BALANCE_SERVER_IMP_H__

#pragma once

#include "commonpacket.h"
#include "CommonServer.h"
#include "CommonRoutine.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
///授权均衡服务器
class CBalanceServer : public ICommonServer, public CPAKHandler
{
public:
    CBalanceServer(void);
    virtual ~CBalanceServer(void);
    // CComponent
    // Command to set param value
    virtual UInt   Command(PCXStr pszCMD, uintptr_t utParam) OVERRIDE;
    virtual UInt   Update(void) OVERRIDE;

    virtual UInt   Init(CEventHandler& EventHandlerRef, CServerConfig& ConfigRef) OVERRIDE;
    virtual void   Exit(void) OVERRIDE;

    virtual bool   Start(void) OVERRIDE;
    virtual bool   Pause(bool bPause = true) OVERRIDE;
    virtual void   Stop(void) OVERRIDE;
    // CPAKHandler
    virtual bool   OnTcpDispatch(const PacketPtr& PktPtr, PTCP_PARAM pTcp) OVERRIDE;
    virtual bool   OnUdpDispatch(const PacketPtr& PktPtr, PUDP_PARAM pUdp) OVERRIDE;
    virtual bool   OnTcpAccept(Socket sAccept, Socket sListen) OVERRIDE;//
    virtual bool   OnTcpConnect(UInt uError, Socket sConnect) OVERRIDE;
    virtual bool   OnTcpRecv(size_t stSize, PTCP_PARAM pTcp) OVERRIDE;//
    virtual bool   OnTcpSend(UInt uQueueLimit, Socket sSocket) OVERRIDE;//
    virtual bool   OnTcpClose(Socket sSocket, ULLong ullLiveData) OVERRIDE;

    virtual bool   OnUdpRecv(size_t stSize, PUDP_PARAM pUdp) OVERRIDE;//
    virtual bool   OnUdpSend(UInt uQueueLimit, Socket sSocket) OVERRIDE;//
    virtual bool   OnUdpClose(Socket sSocket, ULLong ullLiveData) OVERRIDE;
    // Routine
    virtual Socket_t          GetSocket(UInt uType) OVERRIDE;
    virtual PSERVER_INFO      GetServerInfo(UInt uType) OVERRIDE;
    virtual PSVR_COMMON_MAP   GetServerMap(UInt uType) OVERRIDE;
    virtual PRESULT_CHAIN     GetServerSort(UInt uType) OVERRIDE;
    virtual CServerConfig&    GetConfig(void) OVERRIDE;
    virtual CFileLog&         GetFileLog(void) OVERRIDE;
    virtual CEventHandlerPtr& GetMgrHandler(void) OVERRIDE;
    virtual CNetworkPtr&      GetNetworkPtr(void) OVERRIDE;
private:
    CBalanceServer(const CBalanceServer&);
    CBalanceServer& operator=(const CBalanceServer&);
    /// 配置相关
    bool  LoadConfig(void);
    void  UnloadConfig(void);

    bool  StartConnectCenterServer(void);
    bool  StartListenExternal(void);
    bool  CheckConnectCenterServer(void);
    bool  CheckListenExternal(void);
    void  StopConnectCenterServer(void);
    void  StopListenExternal(void);

    /// 向同步管理服务器注册/注销
    void  LinkCenterServer(void);
    void  UnlinkCenterServer(void);

    /// 同步服务器信息给控制台
    bool  SyncServerInfo(void);
    /// 同步授权网关服务器负载
    bool  SyncAuthorSortInfo(CStream& Stream);

    bool  LoadExtConfig(void);
    bool  LoadExtRoutine(CKVNode& Root);
    bool  CreateRTTIObject(PCXStr pszObject, PCXStr pszName, PCXStr pszModule);
    bool  UnloadExtConfig(void);
    bool  UnloadExtRoutine(void);
private:
    Int                 m_nStatus;         ///< 服务器状态
    Int                 m_nCenterLink;     ///< 连接同步管理服务器状态
    // 框架例程开关, 由框架例程通过调用Command修改服务器实例对应参数
    Int                 m_nServerAck;      ///< 例程需要处理连接上服务器ACK信息PAKE_LINKACK/PAKE_UNLINKACK
    Int                 m_nSyncInfo;       ///< 例程需要处理服务器PAKE_LINK/PAKE_UPDATE同步信息时增加其他数据
    Int                 m_nCommonEvent;    ///< 例程需要处理服务器内部通用PAKE_COMMON_BEGIN/PAKE_COMMON_END事件
    //
    CServerConfig*      m_pConfig;         ///< 配置
    Socket              m_sConnectCenter;  ///< 内网, 连接同步管理服务器
    Socket              m_sListenExternal; ///< 外网, 监听外网端
    CFileLog            m_FileLog;         ///< 简单文本日志
    CEventHandlerPtr    m_MgrHandler;      ///< 控制台回调接口
    CNetworkPtr         m_NetworkPtr;      ///< 网络
    CCommonRoutinePtr   m_RoutinePtr;      ///< 例程处理
    BALANCE_ADDR        m_ServerInfo;      ///< 本服务器信息
    SERVER_INFO         m_AuthorInfo;      ///< 授权网关服务器组统计数据
    RESULT_CHAIN        m_SortChain;       ///< 授权网关服务器排序结果
    SVR_AUTHOR_MAP      m_Author;          ///< 授权网关服务器信息
};

INLINE CBalanceServer::CBalanceServer(void)
: m_nStatus(STATUSS_NONE)
, m_nCenterLink(STATUSL_NONE)
, m_nServerAck(FALSE)
, m_nSyncInfo(FALSE)
, m_nCommonEvent(FALSE)
, m_pConfig(nullptr)
, m_sConnectCenter(0)
, m_sListenExternal(0)
, m_FileLog(false)
{
}

INLINE CBalanceServer::~CBalanceServer(void)
{
}

INLINE CBalanceServer::CBalanceServer(const CBalanceServer&)
: m_nStatus(STATUSS_NONE)
, m_nCenterLink(STATUSL_NONE)
, m_nServerAck(FALSE)
, m_nSyncInfo(FALSE)
, m_nCommonEvent(FALSE)
, m_pConfig(nullptr)
, m_sConnectCenter(0)
, m_sListenExternal(0)
, m_FileLog(false)
{
}

INLINE CBalanceServer& CBalanceServer::operator=(const CBalanceServer&)
{
    return (*this);
}

INLINE bool CBalanceServer::OnTcpAccept(Socket, Socket)
{
    return false;
}

INLINE bool CBalanceServer::OnTcpRecv(size_t, PTCP_PARAM)
{
    return false;
}

INLINE bool CBalanceServer::OnTcpSend(UInt, Socket)
{
    return true;
}

INLINE bool CBalanceServer::OnUdpRecv(size_t, PUDP_PARAM)
{
    return false;
}

INLINE bool CBalanceServer::OnUdpSend(UInt, Socket)
{
    return true;
}

INLINE Socket_t CBalanceServer::GetSocket(UInt uType)
{
    if (uType == PAKT_CENTER)
    {
        return m_sConnectCenter;
    }
    else if (uType == PAKT_BALANCE)
    {
        return m_sListenExternal;
    }
    return 0;
}

INLINE PSERVER_INFO CBalanceServer::GetServerInfo(UInt uType)
{
    if (uType == PAKT_AUTHOR)
    {
        return (&m_AuthorInfo);
    }
    return (&m_ServerInfo);
}

INLINE PSVR_COMMON_MAP CBalanceServer::GetServerMap(UInt uType)
{
    if (uType == PAKT_AUTHOR)
    {
        return (PSVR_COMMON_MAP)&m_Author;
    }
    return nullptr;
}

INLINE PRESULT_CHAIN CBalanceServer::GetServerSort(UInt uType)
{
    if (uType == PAKT_AUTHOR)
    {
        return &m_SortChain;
    }
    return nullptr;
}

INLINE CServerConfig& CBalanceServer::GetConfig(void)
{
    return (*m_pConfig);
}

INLINE CFileLog& CBalanceServer::GetFileLog(void)
{
    return m_FileLog;
}

INLINE CEventHandlerPtr& CBalanceServer::GetMgrHandler(void)
{
    return m_MgrHandler;
}

INLINE CNetworkPtr& CBalanceServer::GetNetworkPtr(void)
{
    return m_NetworkPtr;
}

#endif // __BALANCE_SERVER_IMP_H__
